# hierarchical file browser
# (c) 2008-2009 NIXON Development Corporation.

import wx

import os, stat
import local, format, menus, transfer, common, dragdrop

from wx.lib.throbber import Throbber
from wx.lib.scrolledpanel import ScrolledPanel
import wx.lib.delayedresult as delayedResult

class browserPanel(wx.Panel):
	pos = -1
	realImage = None
	showWindow = False
	
	class selectTimer(wx.Timer):
		def __init__(self, prnt):
			self.prnt = prnt
			wx.Timer.__init__(self)
			
		def Notify(self):
			if self.prnt.box:
				self.prnt.getGenericInfo(self.prnt.box, self.prnt.blLocal)
			
	def __init__(self, prnt, boxWidth, blLocal, listing=False):
		wx.Panel.__init__(self, prnt.splitBrowser, style=wx.FULL_REPAINT_ON_RESIZE)
		self.hdlFrame = prnt
		
		self.st = self.selectTimer(self)
		
		self.pathToIcons = prnt.pathToIcons
		self.strIconExt = prnt.strIconExt
		
		self.blLocal = blLocal
		self.resetLists()
		self.iconPackage = prnt.iconPackage
		
		self.boxWidth = boxWidth
		sizer = wx.BoxSizer(wx.VERTICAL)

		#self.spBrowser = wx.ScrolledWindow(self)
		#self.spBrowser.SetScrollbars(1, 0, 1, 0)
		self.spBrowser = ScrolledPanel(self)
		self.spBrowser.SetupScrolling(1, 0, 1, 0)
		
		self.sizerBrowser = wx.BoxSizer(wx.HORIZONTAL)

		self.spInfo = wx.ScrolledWindow(self.spBrowser)
		self.spInfo.SetMinSize((self.hdlFrame.boxWidth - 1, -1))
		self.spInfo.SetFont(wx.Font(wx.smallFontSize, wx.DEFAULT, wx.NORMAL, wx.NORMAL, False, wx.defaultFont))
		self.spInfo.Bind(wx.EVT_PAINT, self.onSpInfoPaint)
		
		self.spInfo.SetBackgroundColour((255,255,255))
		self.spInfo.SetScrollRate(0, 1)
		
		self.spInfo.Bind(wx.EVT_MOUSE_EVENTS, self.onSpInfoMouse)
		
		self.sizerBrowser.Add(self.spInfo, 0, wx.ALIGN_RIGHT | wx.EXPAND | wx.LEFT, 1)
		
		self.spBrowser.SetSizer(self.sizerBrowser)
		sizer.Add(self.spBrowser, 3, wx.EXPAND)
		
		self.statusBar = wx.Panel(self)
		self.statusBar.Bind(wx.EVT_PAINT, self.onStatusPaint)
		self.statusBar.SetBackgroundColour((255,255,255))
		self.statusBar.SetForegroundColour((64,64,64))
		
		statusSizer = wx.BoxSizer(wx.HORIZONTAL)
		
		try:
			self.throbber = Throbber(self.statusBar, -1, self.iconPackage.iconThrobber, frameDelay=0.05, frameWidth=16, frames=12)
			self.throbber.Show(False)
		except: self.throbber = None
		
		self.sbError = wx.StaticBitmap(parent=self.statusBar, bitmap=self.iconPackage.iconSmallError)
		self.sbError.Show(False)

		self.statusText = wx.StaticText(parent=self.statusBar, label='Loading...', style=wx.ALIGN_CENTRE | wx.ST_NO_AUTORESIZE)
		 
		statusFlags = wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL | wx.ALL
		statusSizer.Add(self.sbError, 0, statusFlags, 3)
		statusSizer.Add(self.statusText, 1, statusFlags, 5)
		statusSizer.Add(self.throbber, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT, 5)
		
		self.statusBar.SetSizer(statusSizer)

		self.statusBar.Show(False)		
		sizer.Add(self.statusBar, 0, wx.EXPAND)

		sizerInfo = wx.BoxSizer(wx.VERTICAL)
		#sizerInfo.Add((160, 0))

		self.sbPreview = wx.StaticBitmap(parent=self.spInfo)
		self.sbPreview.Bind(wx.EVT_LEFT_UP, self.onPreviewClick)
		sizerInfo.Add(self.sbPreview, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5)

		self.lblName = wx.StaticText(label='Preview', parent=self.spInfo)
		self.lblName.SetFont(wx.boldFont)
		self.lblName.SetMaxSize((self.hdlFrame.boxWidth - 10, 5))
		
		sizerInfo.Add(self.lblName, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5)
		
		if self.blLocal: strLabel = '&Upload'
		else: strLabel = '&Download'
		
		self.btnTransfer = wx.Button(parent=self.spInfo, label=strLabel)
		self.btnTransfer.Show(False)
		self.btnTransfer.Bind(wx.EVT_BUTTON, self.onBtnTransfer)
		sizerInfo.Add(self.btnTransfer, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 4)
		
		self.lblSize = common.titleLabel('Size', self.spInfo)
		self.lblGroup = common.titleLabel('Group', self.spInfo)
		self.lblOwner = common.titleLabel('Owner', self.spInfo)
		self.lblChanged = common.titleLabel('Date', self.spInfo)
		self.lblPerms = common.titleLabel('Rights', self.spInfo)
		self.lblEtc = common.titleLabel('', self.spInfo)
		self.lblEtc.Show(False)
		
		self.stSize = wx.StaticText(label='Unknown', parent=self.spInfo)
		self.stGroup = wx.StaticText(label='Unknown', parent=self.spInfo)
		self.stOwner = wx.StaticText(label='Unknown', parent=self.spInfo)
		self.stChanged = wx.StaticText(label='Unknown', parent=self.spInfo)
		self.stPerms = wx.StaticText(label='Unknown', parent=self.spInfo)
		self.stEtc = wx.StaticText(parent=self.spInfo)
		self.stEtc.Show(False)
		
		self.stChanged.Bind(wx.EVT_LEFT_UP, self.onStChangedClick)

		sizerInfoGrid = wx.FlexGridSizer(cols=2, hgap=5, vgap=5)

		styleLeft = wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL
		styleRight = wx.EXPAND | wx.RIGHT
		
		sizerInfoGrid.Add(self.lblEtc, 0, styleLeft)
		sizerInfoGrid.Add(self.stEtc, 0, styleRight)
		
		sizerInfoGrid.Add(self.lblSize, 0, styleLeft)
		sizerInfoGrid.Add(self.stSize, 0, styleRight)

		sizerInfoGrid.Add(self.lblChanged, 0, styleLeft)
		sizerInfoGrid.Add(self.stChanged, 0)
		
		sizerInfoGrid.Add(self.lblOwner, 0, styleLeft)
		sizerInfoGrid.Add(self.stOwner, 0, styleRight)
		
		sizerInfoGrid.Add(self.lblGroup, 0, styleLeft)
		sizerInfoGrid.Add(self.stGroup, 0, styleRight)
		
		sizerInfoGrid.Add(self.lblPerms, 0, styleLeft)
		sizerInfoGrid.Add(self.stPerms, 0, styleRight)

		sizerInfo.Add(sizerInfoGrid, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 8)
			
		self.spInfo.SetSizer(sizerInfo)
		self.SetSizer(sizer)

		self.spBrowser.SetBackgroundColour((255,255,255))
	
	def doThrobber(self, bl=True):
		self.throbber.Show(bl)
		
		if bl:
			self.throbber.Start()
		else:
			self.throbber.Stop()
			
		self.Layout()
		#self.statusBar.Layout()
		
	def doStatus(self, bl=True, error=False):
		self.statusBar.Show(bl)
		self.sbError.Show(error)
		
		self.Layout()
		self.statusBar.Layout()
		self.statusBar.Refresh()
		
	def showError(self, strMessage):
		self.doStatus(True, True)
		self.statusText.SetLabel(strMessage)
		
	def onSpInfoMouse(self, event):
		pos = event.GetPosition()[1]
		
		if event.LeftDown():
			self.pos = pos
				
		if event.LeftIsDown():
			scrollPos = self.spInfo.GetViewStart()[1]
			self.spInfo.Scroll(0, scrollPos + (self.pos - pos))
			self.pos = pos
			
		event.Skip()

	def resetLists(self):
		self.lstBrowsers = []
		self.lstCrumbs = []
		self.lstIcons = []
		self.lstSizers = []
		self.lstArrows = []

	def addListBox(self, path = '/', local = False, dontFit=False):
		lenB = len(self.lstBrowsers)
		bpIcon = self.iconPackage.iconSmallFile
		if local == True:
			if lenB == 0:
				if self.hdlFrame.blWin:
					lastdir = 'Computer'
					bpIcon = self.iconPackage.iconSmallComputer
				else:
					lastdir = '/'
					bpIcon = self.iconPackage.iconSmallDrive
			else:
				if lenB == 1 and self.hdlFrame.blWin:
					bpIcon = self.iconPackage.iconSmallDrive
				else:
					bpIcon = self.iconPackage.iconSmallDir
					
				pleft = self.lstBrowsers[lenB - 1].Rect[0] + self.boxWidth
				if path.find('/') != -1:
					if path[1:-1] != ':':
						lastdir = path[path.rfind('/') + 1:]
					else:
						lastdir = path[0:2].capitalize()
				else:
					lastdir = path  
		else:
			if lenB == 0:
				lastdir = '/'
				bpIcon = self.iconPackage.iconSmallServer
			else:
				lastdir = path
				bpIcon = self.iconPackage.iconSmallDir
			
		self.lstSizers.append(wx.BoxSizer(wx.VERTICAL))
		
		sizerTop = wx.BoxSizer(wx.HORIZONTAL)
		self.lstSizers[-1].Add(sizerTop, 0, wx.EXPAND | wx.TOP, 4)
		
		self.lstIcons.append (wx.StaticBitmap(bitmap=bpIcon, parent=self.spBrowser))
		sizerTop.Add(self.lstIcons[-1], 0, wx.LEFT | wx.RIGHT, 4)
		
		self.lstCrumbs.append (wx.StaticText(self.spBrowser, label=lastdir, style=wx.ALIGN_CENTER))
		self.lstCrumbs[-1].blLocal = local
		if wx.Platform != '__WXMSW__':
			self.lstCrumbs[-1].SetFont(wx.Font(12, wx.DEFAULT, wx.NORMAL, wx.NORMAL, False))
		sizerTop.Add(self.lstCrumbs[-1], 1, wx.EXPAND | wx.ALL, 2)
		
		self.lstArrows.append (wx.StaticBitmap(bitmap=self.iconPackage.iconNextDir, parent=self.spBrowser))
		sizerTop.Add(self.lstArrows[-1], 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT, 2)
		
		self.lstArrows[-1].Show(False)
		if lenB != 0:
			self.lstArrows[-2].Show(True)
			
		self.lstBrowsers.append (common.extListCtrl(self.spBrowser, (self.boxWidth - 1, 1), \
			wx.LC_REPORT | wx.LC_NO_HEADER | wx.BORDER_NONE | wx.LC_EDIT_LABELS, self))
		self.lstBrowsers[-1].Label = path
		
		self.lstSizers[-1].Add(self.lstBrowsers[-1], 1, wx.EXPAND)
		
		self.lstBrowsers[-1].InsertColumn(0, '')
		
		# Events
		self.lstBrowsers[-1].Bind(wx.EVT_LIST_ITEM_SELECTED, self.onListClick)
		self.lstBrowsers[-1].Bind(wx.EVT_LIST_ITEM_DESELECTED, self.onListClick)
		self.lstBrowsers[-1].Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.onListDoubleClick)
		
		self.lstCrumbs[-1].Bind(wx.EVT_MOUSE_EVENTS, self.stCrumbs_Mouse)
		
		inNumber = lenB + 1
		self.lstBrowsers[-1].Number = inNumber
		self.lstCrumbs[-1].Number = inNumber
		
		self.sizerBrowser.Insert(lenB, self.lstSizers[-1], 0, wx.EXPAND | wx.LEFT, 1)
		self.intBox = inNumber
		self.spInfo.Show(False)
		
		if not dontFit:
			self.fitBrowser(True)
			self.spBrowser.Refresh()
		
	def removeListBox(self, index):
		if self.blLocal == True and self.hdlFrame.blWin and index == 0: return
		lenB = len(self.lstBrowsers)
		
		for x in range(lenB, index, -1):
			for x in (self.lstBrowsers, self.lstCrumbs, self.lstArrows, self.lstIcons):
				x[-1].Destroy()
				x.pop()

			self.lstSizers[-1].Clear()
			self.sizerBrowser.Remove(self.lstSizers[-1])
			self.lstSizers.pop()

		self.lstArrows[-1].Show(False)

		intEnd = self.boxWidth * (index + 1) + self.spInfo.GetSize()[0]
		#self.spBrowser.SetVirtualSize((intEnd, -1))
		
		self.spBrowser.Refresh()
		
	def scrollEffectConsumer(self, delayedresult): pass
	
	def scrollEffect(self, intSpeed = -1):
		vSize = self.spBrowser.GetVirtualSize()[0]
		start = self.spBrowser.GetViewStart()[0]
		
		#if vSize - self.spInfo.GetSize()[0] > self.spInfo.GetRect()[0] and self.spInfo.Shown: return
		
		if intSpeed == -1:
			intSpeed = self.hdlFrame.boxWidth / 50

		tpRange = range(0, vSize - start + self.spBrowser.GetSize()[0], intSpeed)
		
		for x in tpRange:
			self.spBrowser.Scroll(start + x, 0)
			
		self.lstBrowsers[-1].SetFocus()
		
	def onListClick(self, event):
		self.box = event.GetEventObject()
		if not self.box.ignoreListEvents:
			#self.st.Start(75, True)
			scroll = len(self.lstBrowsers) == self.box.Number
			if not(self.box.Number == 0 and self.blLocal and self.hdlFrame.blWin):
				self.removeListBox(self.box.Number)
			self.getGenericInfo(self.box, self.blLocal, scroll)

		event.Skip()
	
	def onListDoubleClick(self, event):
		self.box = None
		box = event.GetEventObject()
		idx = box.Number
		sel = box.getSelections()
		ls = len(sel)
		if ls == 0: return
		sel = box.GetItem(sel[0]).GetText()
		lbl = box.Label
		
		if idx == 1 and self.hdlFrame.blWin and self.blLocal:
			self.removeListBox(1)
			self.addListBox('Local drive ' + sel.upper(), True)

			self.hdlFrame.UpdateLocal(sel + '/')
		else:
			if ls == 1: # singular file
				pwf = lbl + '/' + sel
				
				if self.blLocal:
					type = local.getType(pwf)
				else:
					sel = self.hdlFrame.dirList.getReals(pwf)
					type = self.hdlFrame.dirList.getType(pwf)
					
				if type >= 2: # disc or directory
					if sel == '..':
						if box != 1: self.removeListBox(idx - 1)
					elif sel != '.':
						self.removeListBox(idx)
						self.addListBox(sel)
						
						if self.blLocal:
							self.hdlFrame.UpdateLocal(pwf)
						else:
							self.hdlFrame.UpdateList(pwf)

				elif type == 1: # link
					#self.sbPreview.SetBitmap(self.iconPackage.iconPreLink)
					gtpath = self.hdlFrame.dirList.getDest(pwf)
					
					self.removeListBox(idx)
					linkItem = box.GetNextItem(-1, state=wx.LIST_STATE_SELECTED)
					box.SetItemState(linkItem, 0, wx.LIST_STATE_SELECTED)
					
					if self.blLocal:
						self.hdlFrame.TraverseLocal(gtpath, lbl)
					else:
						self.hdlFrame.TraversePath(gtpath, lbl)
				elif type == 0:
					preview.windowPreview(pwf, self.blLocal)
							
	def stCrumbs_Mouse(self, event):
		win = event.GetEventObject()
		evt = event.GetEventType()

		clr = None
		
		if event.LeftDown():
			clr = (240,240,240)
		elif event.LeftUp():
			clr = wx.NullColour
			self.Crumb_Click(event)
			
		win.SetBackgroundColour(clr)
		win.Refresh()
		
	def setPreview(self, bool):
		for x in (self.stOwner, self.stGroup, \
			self.stSize, self.stChanged, \
			self.lblOwner, self.lblGroup, self.lblSize, \
			self.lblChanged, self.stPerms, self.lblPerms):
			x.Show(bool)
		
		self.stEtc.Show(False)
		self.lblEtc.Show(False)
		self.spInfo.Layout()
		
	def imagePreview(self, bmp):
		self.realImage = bmp
		self.blPreview = True
		self.sbPreview.SetBitmap(preview.scaleImage(bmp, self.boxWidth - 72))
		self.sbPreview.SetSize((-1, -1))
		self.sbPreview.Center(wx.HORIZONTAL)
		self.lblEtc.Label = 'Area'
		self.stEtc.Label = '%d %s %d' % (bmp.GetWidth(), wx.multiply, bmp.GetHeight())
		self.lblEtc.Shown = True
		self.stEtc.Shown = True
		self.spInfo.Layout()
		self.spInfo.Refresh()
		
	def setTempImage(self, argv):
		bmp = wx.Bitmap(argv)
		self.imagePreview(bmp, self)
		self.spInfo.FitInside()
		self.spInfo.Refresh()
		
	def Crumb_Click(self, event):
		box = event.GetEventObject()
		bn = box.Number
		self.removeListBox(bn)
		self.setPreview(True)
		preview = True
		lb = self.lstBrowsers[bn - 1]
		
		if self.blLocal:
			if bn != 1:
				if bn == 2 and self.hdlFrame.blWin:
					bmp = self.iconPackage.iconPreDrive
					self.btnTransfer.Show(False)
					self.hdlFrame.UpdateLocal(lb.Label + '/')
				else:
					bmp = self.iconPackage.iconPreFolder
					self.hdlFrame.UpdateLocal(lb.Label)
			else:
				if self.hdlFrame.blWin:
					bmp = self.iconPackage.iconPreComputer
					self.btnTransfer.Show(False)
				else:
					bmp = self.iconPackage.iconPreDrive
					
				self.setPreview(False)
				preview = False
		else:
			if bn == 1:
				preview = False
			else:
				bmp = self.iconPackage.iconPreFolder

			self.doThrobber(True)
			self.doStatus(True)
			
			if bn == 1 and not(self.blLocal) and self.hdlFrame.mFTP == None:
				self.hdlFrame.resetFTP()
			else:
				self.hdlFrame.reloadRemote(bn-1)

		self.spInfo.Show(preview)
		if preview:
			self.sbPreview.SetBitmap(bmp)
			self.showInfo(common.getInfo(self.hdlFrame, self.blLocal, self.lstBrowsers[bn-1].Label, box.Label))
			
		self.fitBrowser(preview)

	def onPreviewClick(self, event):
		if self.blPreview:
			pw = common.previewWindow(True, self.lblName.Label)
			pw.setImage(self.realImage)
			
	def getGenericInfo(self, box, blLocal = False, removed = False):
		self.setPreview(True)
		sel = box.getSelections()
		sl = len(sel)
		lbl = box.Label
		self.intBox = box.Number
		
		self.sbPreview.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
		
		self.blPreview = False
		self.doThrobber(False)
		self.doStatus(False)
		
		if sl == 0:
			self.setPreview(False)
			self.spInfo.Show(False)
			self.sbPreview.SetBitmap(self.iconPackage.iconPreFolder)
			self.lblName.Label = self.lstCrumbs[box.Number-1].Label
			
		elif blLocal and box.Number == 1 and self.hdlFrame.blWin:
			sel = box.GetItem(sel[0]).GetText()
			self.btnTransfer.Show(False)
			self.setPreview(False)
			self.spInfo.Show(False)
			
		elif sl == 1:
			sel = box.GetItem(sel[0]).GetText()
			self.btnTransfer.Show(True)
			pwf = lbl + '/' + sel
			
			if blLocal:
				intType = local.getType(pwf)
				if intType == 0: type = '-'
				elif intType == 1: type = 'l'
				else: type = 'd'
			else:
				type = self.hdlFrame.dirList.getPerms(pwf)[:1]
			
			tpInfo = common.getInfo(self.hdlFrame, blLocal, pwf, sel)
			if type != 'd' and type != 'l': # normal file	
				if preview.needsPreview(sel) != False:
					self.sbPreview.SetCursor(wx.StockCursor(wx.CURSOR_HAND))
					if blLocal:
						bmp = wx.Bitmap(pwf)
						self.imagePreview(bmp)
					else:
						preview.imagePreview(pwf, False, self.imagePreview)
				else:
					self.sbPreview.SetBitmap(self.iconPackage.iconPreFile)
				self.showInfo(tpInfo, False, removed)
				
			else: # folder
				if self.spInfo.Shown:
					self.sbPreview.SetBitmap(self.iconPackage.iconPreFolder)
					self.showInfo(tpInfo)
					
				if self.hdlFrame.infoDlg: self.hdlFrame.infoDlg.showInfo(tpInfo, self.blLocal)

		elif sl > 1:
			self.setPreview(False)
			size = 0
			
			for x in range(0, sl):
				name = box.GetItem(sel[x]).GetText()
				pwf = lbl + '/' + name
				
				if blLocal:
					stats = os.stat(pwf)
					size += int(stats[stat.ST_SIZE])
				else:
					size += int(self.hdlFrame.dirList.getSizes(pwf))
			
			self.spInfo.Show(True)
			self.sbPreview.SetBitmap(self.iconPackage.iconPreMulti)
			self.setPreview(False)
			
			strItems = '%d of %d items' % (sl, box.GetItemCount())
			strSize = format.parseSize(size)
			
			self.lblName.SetLabel(strItems)
			self.stSize.SetLabel(strSize)
			self.stSize.Show()
			self.lblSize.Show()
			
			self.statusText.SetLabel(strItems + ', ' + strSize)
			
			self.spInfo.Show()
			self.smartStatus()
			self.doThrobber(False)
			return
		
	def showInfo(self, tpInfo, status=False, scroll=False):
		strSize = format.parseSize(tpInfo[1])
		self.stSize.SetLabel(strSize)
		
		strDate = format.parseDate(tpInfo[2], self.hdlFrame.relativeDates)
		self.stChanged.SetLabel(strDate)
		self.stChanged.SetToolTip(wx.ToolTip(format.parseDate(tpInfo[2], not(self.hdlFrame.relativeDates))))
		self.stChanged.realDate = tpInfo[2]
		
		blAccess = tpInfo[3] != ''
		
		for x in (self.lblOwner, self.stOwner, self.lblGroup, self.stGroup, self.lblPerms, self.stPerms):
			x.Show(blAccess)

		if blAccess:
			self.stOwner.SetLabel(tpInfo[3])
			self.stGroup.SetLabel(tpInfo[4])
			self.stPerms.SetLabel(tpInfo[5])
			
		self.lblName.Label = tpInfo[0]
			
		intOverflow = self.hdlFrame.boxWidth / 1.5 / self.lblName.GetCharWidth()
		
		if len(self.lblName.Label) > intOverflow and self.lblName.Label.find(' ') == -1:
			self.lblName.SetToolTip(wx.ToolTip(self.lblName.Label))
			self.lblName.Label = format.shorten(self.lblName.Label, intOverflow)
		else:
			self.lblName.SetToolTip(wx.ToolTip(''))
		
		self.stChanged.Wrap(self.boxWidth - 90)
		self.spInfo.Show(True)
		self.fitBrowser(scroll)
		
		if self.hdlFrame.infoDlg: self.hdlFrame.infoDlg.showInfo(tpInfo, self.blLocal)
		
		if status:
			if self.smartStatus():
				self.doStatus(True)
				self.statusText.SetLabel(tpInfo[0] + '\t   Size: ' + strSize + '\t   Modified: ' + strDate)
		
	def smartStatus(self):
		intOffset = self.spBrowser.GetVirtualSize()[0] - self.spBrowser.GetViewStart()[0] - self.spBrowser.GetClientSize()[0]
		
		x = self.spInfo.GetSize()[0]
		x1 = self.stChanged.GetRect()[0] + self.stChanged.GetSize()[0]
		x2 = self.lblName.GetRect()[0] + self.lblName.GetSize()[0]
		
		if x1 > x2:
			intThreshold = x - x1
		else:
			intThreshold = x - x2
		
		blStatus = intOffset >= intThreshold
		#self.doStatus(blStatus)
		return False
		
	def onSpInfoPaint(self, event):
		if self.statusBar.Shown:
			self.smartStatus()
		event.Skip()
		
	def fitBrowser(self, scroll=False):		
		lenB = len(self.lstBrowsers)
		
		if self.spInfo.Shown:
			factor = lenB + 1
		else:
			factor = lenB
		
		self.spBrowser.Layout()
		infoPos = self.spInfo.GetRect()[0] + self.spInfo.GetSize()[0]
		browserPos = self.spBrowser.GetViewStart()[0] + self.spBrowser.GetClientSize()[0]

		if infoPos >= browserPos or scroll:	
			intEnd = self.boxWidth * (factor)
			self.spBrowser.SetVirtualSize((intEnd, -1))
		
		if self.hdlFrame.blMac:
			self.spBrowser.Scroll(intEnd, 0)
		else:
			delayedResult.startWorker(self.scrollEffectConsumer, self.scrollEffect)
			
		self.spInfo.Layout()
		self.spInfo.Refresh()
		self.spBrowser.Layout()
		self.spBrowser.Refresh()
		
	def onStChangedClick(self, event):
		self.hdlFrame.relativeDates = not(self.hdlFrame.relativeDates)
		self.stChanged.SetToolTip(wx.ToolTip(self.stChanged.Label))
		self.stChanged.SetLabel(format.parseDate(self.stChanged.realDate, self.hdlFrame.relativeDates))
		self.stChanged.Wrap(110)
		self.fitBrowser(-1)
		
	def onBtnTransfer(self, event):
		handle = self.hdlFrame.mFTP
		box = self.lstBrowsers[self.intBox - 1]
		
		lstFiles = []
		
		for x in box.getSelections():
			s = box.GetItemText(x)
			lstFiles.append(s)
			
		if self.blLocal:
			otherBox = self.hdlFrame.pnRemote.lstBrowsers[-1]
		else:
			otherBox = self.hdlFrame.pnLocal.lstBrowsers[-1]
			
		print('Added %s to transfer queue.' % repr(lstFiles))
		handle.transfer(box.Label, lstFiles, self.hdlFrame, self.blLocal, otherBox)
		#handle.transfer(box.Label, lstFiles, self.hdlFrame, self.blLocal)
		
	def onStatusPaint(self, event):
		dc = wx.PaintDC(self.statusBar)
		dc.SetPen(wx.Pen((216,216,216), 1))
		
		tpSize = self.statusBar.GetSize()
		
		dc.DrawLine(0, 0, tpSize[0], 0)
		dc.DrawLine(0, tpSize[1]-1, tpSize[0], tpSize[1]-1)
		event.Skip()